#pragma once
#include <Rz/Object.h>
#include <Rz/Collections/List.h>
#include <Rz/Collections/InitializerList.h>
#include "VertexElement.h"

namespace Rz { namespace Graphics { namespace Render {

class VertexDescription :
	public Object
{
	public:
		RZ_RTTI(Rz::Graphics::Render, VertexDescription);
		RZ_RTTI_IMPLEMENTS(Object);
		RZ_RTTI_END;

		VertexDescription()
		{

		}

		VertexDescription(const Collections::IEnumerable<VertexElement>& elements)
			: _vertexStride(0)
		{
			_vertexElements.Add(elements);

			for (auto& e : elements)
			{
				_vertexStride += this->GetElementStride(e.GetVertexElementFormat());
			}
		}

		VertexDescription(const Collections::IEnumerable<VertexElement>& elements, u32 stride)
		{
			_vertexElements.Add(elements);
			_vertexStride = stride;
		}

		const Collections::List<VertexElement>& GetVertexElements() const
		{
			return _vertexElements;
		}

		u32 GetVertexStride() const
		{
			return _vertexStride;
		}

	private:
		RZ_INLINE static u32 GetElementStride(VertexElementFormat format)
		{
            switch (format)
            {
                case VertexElementFormat::NormalizedShort2:
                case VertexElementFormat::Byte4:
                case VertexElementFormat::Color:
                case VertexElementFormat::HalfVector2:
                case VertexElementFormat::Short2:
                case VertexElementFormat::Single:
                    return 4;	// sizeof(float)
                case VertexElementFormat::HalfVector4:
                case VertexElementFormat::NormalizedShort4:
                case VertexElementFormat::Short4:
                case VertexElementFormat::Vector2:
                    return 8;	// 2*sizeof(float)
                case VertexElementFormat::Vector3:
                    return 12;	// 3*sizeof(float)
                case VertexElementFormat::Vector4:
                    return 16;	// 4*sizeof(float)
                default:
					return 0;
            }
		}

		// REVIEW: size_t ?
		u32 _vertexStride;
		Collections::List<VertexElement> _vertexElements;
};

} } }
